package services

import (
	"context"
	"fmt"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/golang/protobuf/ptypes/wrappers"

	context2 "kop/framework/context"
	"kop/framework/errors"
	"kop/modules/battle/models/battle"
	"kop/modules/island/client"
	"kop/pb"
	"kop/pb/service"

	captainC "kop/modules/captain/client"
	roleC "kop/modules/role/client"
)

type IslandService struct {
	context2.Context
}

func (*IslandService) Islands(ctx context.Context, req *wrappers.Int32Value) (*pb.IslandsResp, error) {

	return client.IslandService.Islands(ctx, req)
}

func (*IslandService) Island(ctx context.Context, req *wrappers.Int32Value) (*pb.Island, error) {

	return client.IslandService.Island(ctx, req)
}

func (*IslandService) GetIslands(ctx context.Context, req *wrappers.Int32Value) (*pb.Islands, error) {

	return client.IslandService.GetIslands(ctx, req)
}

func (s *IslandService) Battle(ctx context.Context, req *pb.IslandBattleRequest) (*pb.IslandBattleReply, error) {

	var reply pb.IslandBattleReply

	var roleID = s.GetRoleID(ctx)

	var myIslands, err = client.IslandService.GetIslands(ctx, &wrappers.Int32Value{Value: roleID})
	if err != nil {
		return &reply, err
	}

	var role = roleC.GetRole(roleID)

	var length = len(myIslands.Islands)
	if length >= 3 {
		return &reply, errors.ParamError
	}

	if length == 1 && role.Level < 16 && role.VIP < 5 {

		return &reply, fmt.Errorf("need lv 16 or VIP 5")
	} else if length == 2 && (role.Level < 16 || role.VIP < 5) {

		return &reply, fmt.Errorf("need lv 16 and VIP 5")
	}

	island, err := client.IslandService.Island(ctx, &wrappers.Int32Value{Value: req.IslandID})
	if err != nil {
		return &reply, err
	}

	reply.Fighter1 = captainC.GetByCaptainIDs(roleID, req.CaptainID1, req.CaptainID2, req.CaptainID3, req.CaptainID4, req.CaptainID5)
	reply.Fighter2 = island.Captains
	reply.BattleResult, err = battle.Battle(reply.Fighter1, reply.Fighter2)
	if err != nil {
		return &reply, err
	}

	var res *service.IslandBattleResp
	if reply.BattleResult.Win {

		res, err = client.IslandService.Win(ctx, &service.IslandWinRequest{IslandID: req.IslandID, Captains: reply.Fighter1})

	} else {

		res, err = client.IslandService.Lost(ctx, &wrappers.Int32Value{Value: req.IslandID})
	}

	if err != nil {
		return &reply, err
	}

	reply.Island = res.Island
	reply.PlayNum = res.PlayNum
	reply.PlayCD = res.PlayCD
	reply.Addition = res.Addition
	return &reply, nil
}
func (*IslandService) Leave(ctx context.Context, req *wrappers.Int32Value) (*pb.IslandLeaveResp, error) {

	return client.IslandService.Leave(ctx, req)
}

func (*IslandService) Reports(ctx context.Context, req *empty.Empty) (*pb.IslandReports, error) {

	return client.IslandService.Reports(ctx, req)
}

func (*IslandService) MyIslands(ctx context.Context, req *empty.Empty) (*pb.MyIslandsResp, error) {

	return client.IslandService.MyIslands(ctx, req)
}

func (*IslandService) ServerReports(ctx context.Context, req *empty.Empty) (*pb.IslandReports, error) {

	return client.IslandService.ServerReports(ctx, req)
}

func (*IslandService) GuildRanking(ctx context.Context, req *empty.Empty) (*pb.GuildRankingResp, error) {

	return client.IslandService.GuildRanking(ctx, req)
}

func (*IslandService) RankingAward(ctx context.Context, req *empty.Empty) (*pb.GuildAward, error) {

	return client.IslandService.RankingAward(ctx, req)
}
